home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
tex
/
archives
/
pbmtopk.lzh
/
pbmtopk
/
src
/
pbmtopk.c.orig
< prev
next >
Wrap
Text File
|
1992-05-12
|
25KB
|
1,052 lines
/*
pbmtopk, adapted from "pxtopk.c by tomas rokicki" by AJCD 1/8/90
compile with: cc -o pbmtopk pbmtopk.c -lm -lpbm
*/
#include <stdio.h>
#include <pbm.h>
#include <ctype.h>
extern double atof();
#define MAXPKCHAR 256
#define MAXOPTLINE 200
#define MAXWIDTHTAB 256
#define MAXHEIGHTTAB 16
#define MAXDEPTHTAB 16
#define MAXITALICTAB 64
#define MAXPARAMS 30
#define NAMELENGTH 80
#define true (1)
#define false (0)
#define chr(a) a
#define round(a) ((int)(a+.5))
#define fixword(d) ((int)((double)(d)*1048576))
#define unfixword(f) ((double)(f) / 1048576)
#define fixrange(f) ((f) < 16777216 && (f) > -16777216)
#define designunits(p) ((p)*72.27/(double)resolution/unfixword(designsize))
/* character flags: in order of appearance in option files. */
#define XOFFSET 1
#define YOFFSET 2
#define HORZESC 4
#define VERTESC 8
#define TFMWIDTH 16
#define TFMHEIGHT 32
#define TFMDEPTH 64
#define TFMITALIC 128
typedef int integer ;
typedef char quarterword ;
typedef char boolean ;
typedef quarterword ASCIIcode ;
typedef quarterword eightbits ;
typedef FILE *bytefile ;
typedef unsigned char byte ;
integer resolution, designsize ;
char *filename[MAXPKCHAR] ;
integer xoffset[MAXPKCHAR] ;
integer yoffset[MAXPKCHAR] ;
integer horzesc[MAXPKCHAR] ;
integer vertesc[MAXPKCHAR] ;
byte tfmindex[MAXPKCHAR] ;
byte hgtindex[MAXPKCHAR] ;
byte depindex[MAXPKCHAR] ;
byte italindex[MAXPKCHAR] ;
byte charflags[MAXPKCHAR] ;
bit **bitmap ;
integer smallestch, largestch ;
integer emwidth ;
integer checksum ;
char *codingscheme = "GRAPHIC" ;
char *familyname = "PBM" ;
integer widthtab[MAXWIDTHTAB] ; /* TFM widths */
integer numwidth ; /* number of entries in width table */
integer heighttab[MAXHEIGHTTAB] ;
integer numheight ;
integer depthtab[MAXDEPTHTAB] ;
integer numdepth ;
integer italictab[MAXITALICTAB] ;
integer numitalic ;
integer parameters[MAXPARAMS] ;
integer numparam ;
ASCIIcode xord[128] ;
char xchr[256] ;
bytefile tfmfile, pkfile ;
char tfmname[NAMELENGTH+1], pkname[NAMELENGTH+1] ;
integer pkloc ;
integer bitweight ;
integer outputbyte ;
integer car ;
integer hppp ;
integer width ;
integer height ;
integer power[32] ;
integer
compute_checksum()
{
/*
begin
c0:=bc; c1:=ec; c2:=bc; c3:=ec;
for c:=bc to ec do if char_wd[c]>0 then
begin
temp_width:=memory[char_wd[c]];
if design_units<>unity then
temp_width:=round((temp_width/design_units)*1048576.0);
temp_width:=temp_width + (c+4)*@'20000000; {this should be positive}
c0:=(c0+c0+temp_width) mod 255;
c1:=(c1+c1+temp_width) mod 253;
c2:=(c2+c2+temp_width) mod 251;
c3:=(c3+c3+temp_width) mod 247;
end;
header_bytes[check_sum_loc]:=c0;
header_bytes[check_sum_loc+1]:=c1;
header_bytes[check_sum_loc+2]:=c2;
header_bytes[check_sum_loc+3]:=c3;
end
*/
}
#define add_tfmwidth(v) (add_tfmtable(widthtab, &numwidth, v, MAXWIDTHTAB,\
"TFM width"))
#define add_tfmheight(v) (add_tfmtable(heighttab, &numheight, v, MAXHEIGHTTAB,\
"TFM height"))
#define add_tfmdepth(v) (add_tfmtable(depthtab, &numdepth, v, MAXDEPTHTAB,\
"TFM depth"))
#define add_tfmitalic(v) (add_tfmtable(italictab, &numitalic, v, MAXITALICTAB,\
"Italic correction"))
byte
add_tfmtable(table, count, value, max, name)
integer *table, *count, value, max;
char *name;
{
integer i;
for (i = 0; i < *count; i++) /* search for value in tfm table */
if (table[i] == value) return (byte)i;
if (*count >= max) {
fprintf(stderr, "Too many values in %s table!\n", name) ;
jumpout();
}
if (!fixrange(value)) {
fprintf(stderr, " %s %f for char %d out of range!\n",
name, unfixword(value), car);
jumpout();
}
table[*count] = value ;
return (*count)++ ;
}
add_suffix(name, suffix)
char *name, *suffix ;
{
int haveext = 0;
if (name && strcmp(name, "-")) {
while (*name) {
if (*name == '/') haveext = 0 ;
else if (*name == '.') haveext = 1 ;
name++ ;
}
if (!haveext) {
*name++ = '.';
strcpy(name,suffix) ;
}
}
}
initialize()
{
integer i ;
fprintf(stderr, "This is PBMtoPK, C Version 2.3\n") ;
for (i = 0 ; i <= 31 ; i ++) xchr[i] = '?' ;
xchr[32] = ' ' ;
xchr[33] = '!' ;
xchr[34] = '"' ;
xchr[35] = '#' ;
xchr[36] = '$' ;
xchr[37] = '%' ;
xchr[38] = '&' ;
xchr[39] = '\'' ;
xchr[40] = '(' ;
xchr[41] = ')' ;
xchr[42] = '*' ;
xchr[43] = '+' ;
xchr[44] = ',' ;
xchr[45] = '-' ;
xchr[46] = '.' ;
xchr[47] = '/' ;
xchr[48] = '0' ;
xchr[49] = '1' ;
xchr[50] = '2' ;
xchr[51] = '3' ;
xchr[52] = '4' ;
xchr[53] = '5' ;
xchr[54] = '6' ;
xchr[55] = '7' ;
xchr[56] = '8' ;
xchr[57] = '9' ;
xchr[58] = ':' ;
xchr[59] = ';' ;
xchr[60] = '<' ;
xchr[61] = '=' ;
xchr[62] = '>' ;
xchr[63] = '?' ;
xchr[64] = '@' ;
xchr[65] = 'A' ;
xchr[66] = 'B' ;
xchr[67] = 'C' ;
xchr[68] = 'D' ;
xchr[69] = 'E' ;
xchr[70] = 'F' ;
xchr[71] = 'G' ;
xchr[72] = 'H' ;
xchr[73] = 'I' ;
xchr[74] = 'J' ;
xchr[75] = 'K' ;
xchr[76] = 'L' ;
xchr[77] = 'M' ;
xchr[78] = 'N' ;
xchr[79] = 'O' ;
xchr[80] = 'P' ;
xchr[81] = 'Q' ;
xchr[82] = 'R' ;
xchr[83] = 'S' ;
xchr[84] = 'T' ;
xchr[85] = 'U' ;
xchr[86] = 'V' ;
xchr[87] = 'W' ;
xchr[88] = 'X' ;
xchr[89] = 'Y' ;
xchr[90] = 'Z' ;
xchr[91] = '[' ;
xchr[92] = '\\' ;
xchr[93] = ']' ;
xchr[94] = '^' ;
xchr[95] = '_' ;
xchr[96] = '`' ;
xchr[97] = 'a' ;
xchr[98] = 'b' ;
xchr[99] = 'c' ;
xchr[100] = 'd' ;
xchr[101] = 'e' ;
xchr[102] = 'f' ;
xchr[103] = 'g' ;
xchr[104] = 'h' ;
xchr[105] = 'i' ;
xchr[106] = 'j' ;
xchr[107] = 'k' ;
xchr[108] = 'l' ;
xchr[109] = 'm' ;
xchr[110] = 'n' ;
xchr[111] = 'o' ;
xchr[112] = 'p' ;
xchr[113] = 'q' ;
xchr[114] = 'r' ;
xchr[115] = 's' ;
xchr[116] = 't' ;
xchr[117] = 'u' ;
xchr[118] = 'v' ;
xchr[119] = 'w' ;
xchr[120] = 'x' ;
xchr[121] = 'y' ;
xchr[122] = 'z' ;
xchr[123] = '{' ;
xchr[124] = '|' ;
xchr[125] = '}' ;
xchr[126] = '~' ;
for (i = 127 ; i <= 255 ; i ++) xchr[i] = '?' ;
for (i = 0 ; i <= 127 ; i ++) xord[chr(i)] = 32 ;
for (i = 32 ; i <= 126 ; i ++) xord[xchr[i]] = i ;
for (i = 0 ; i < 32 ; i++) power[i] = 1 << i ;
for (i = 0; i < MAXPKCHAR; i++) {
filename[i] = NULL;
charflags[i] = 0;
}
pkloc = 0 ;
designsize = fixword(1.0) ;
numparam = 0;
widthtab[0] = heighttab[0] = depthtab[0] = italictab[0] = 0 ;
numwidth = numheight = numdepth = numitalic = 1;
smallestch = MAXPKCHAR ;
largestch = -1 ;
emwidth = 0 ;
}
jumpout()
{
exit(1) ;
}
pkbyte(b)
integer b ;
{
if (b < 0) b = b + 256 ;
putc(b, pkfile) ;
pkloc++ ;
}
pkhalfword(a)
integer a ;
{
if (a < 0) a = a + 65536 ;
pkbyte(a >> 8) ;
pkbyte(a & 255) ;
}
pkthreebytes(a)
integer a ;
{
pkbyte((a>>16) & 255) ;
pkbyte((a>>8) & 255) ;
pkbyte(a & 255) ;
}
pkword(a)
integer a ;
{
pkbyte((a>>24) & 255) ;
pkbyte((a>>16) & 255) ;
pkbyte((a>>8) & 255) ;
pkbyte(a & 255) ;
}
pknyb(a)
integer a ;
{
if (bitweight == 16) {
outputbyte = (a<<4) ;
bitweight = 1 ;
} else {
pkbyte(outputbyte + a) ;
bitweight = 16 ;
}
}
writepreamble()
{
integer i ;
char *comment = "PBMtoPK 2.3 output" ;
pkbyte(247) ;
pkbyte(89) ;
pkbyte(strlen(comment)) ;
for (i = 0 ; i < strlen(comment); i++) pkbyte(xord[comment[i]]) ;
pkword(designsize) ;
pkword(checksum) ; /* checksum; calculate if possible */
pkword(hppp) ;
pkword(hppp) ;
}
writepostamble()
{
pkbyte(245) ;
while ((pkloc % 4 != 0)) pkbyte(246) ;
fprintf(stderr, "%d bytes written to packed file.\n", pkloc) ;
}
tfmbyte(b)
integer b ;
{
if (b < 0) b = b + 256 ;
putc(b, tfmfile) ;
}
tfmhalfword(a)
integer a ;
{
if (a < 0) a = a + 65536 ;
tfmbyte(a >> 8) ;
tfmbyte(a & 255) ;
}
tfmword(a)
integer a ;
{
tfmbyte((a>>24) & 255) ;
tfmbyte((a>>16) & 255) ;
tfmbyte((a>>8) & 255) ;
tfmbyte(a & 255) ;
}
writetfmfile()
{
integer totallength ;
integer headersize = 17;
integer i ;
if (largestch - smallestch < 0) {
largestch = 0;
smallestch = 1;
}
if (numparam < 7) /* set default parameters */
switch (numparam) {
case 0: /* slant */
parameters[numparam++] = 0 ;
case 1: /* space */
parameters[numparam++] = fixword(designunits(emwidth/3.0));
case 2: /* space_stretch */
parameters[numparam++] = fixword(unfixword(parameters[1])/2.0) ;
case 3: /* space_shrink */
parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
case 4: /* x_height */
parameters[numparam++] = fixword(0.45);
case 5: /* quad */
parameters[numparam++] = fixword(designunits(emwidth)) ;
case 6: /* extra_space */
parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
}
totallength = 6 + headersize + (largestch+1-smallestch) +
numwidth + numheight + numdepth + numitalic + numparam ;
/* lengths */
tfmhalfword(totallength) ;
tfmhalfword(headersize) ;
tfmhalfword(smallestch) ;
tfmhalfword(largestch) ;
tfmhalfword(numwidth) ;
tfmhalfword(numheight) ;
tfmhalfword(numdepth) ;
tfmhalfword(numitalic) ;
tfmhalfword(0) ; /* lig/kern table */
tfmhalfword(0) ; /* kern table */
tfmhalfword(0) ; /* extensible char table */
tfmhalfword(numparam) ;
/* header */
tfmword(checksum) ;
tfmword(designsize) ;
if (strlen(codingscheme) > 39) tfmbyte(39) ;
else tfmbyte(strlen(codingscheme)) ;
for (i = 0; i < 39; i++)
if (*codingscheme) tfmbyte(xord[*codingscheme++]) ;
else tfmbyte(0) ;
if (strlen(familyname) > 19) tfmbyte(19) ;
else tfmbyte(strlen(familyname)) ;
for (i = 0; i < 19; i++)
if (*familyname) tfmbyte(xord[*familyname++]) ;
else tfmbyte(0) ;
/* char_info */
for (car = smallestch; car <= largestch; car++)
if (filename[car]) {
tfmbyte(tfmindex[car]) ;
tfmbyte((hgtindex[car]<<4) + depindex[car]) ;
tfmbyte(italindex[car]<<2) ;
tfmbyte(0) ;
} else tfmword(0) ;
/* width */
for (i = 0; i < numwidth; i++) tfmword(widthtab[i]) ;
/* height */
for (i = 0; i < numheight; i++) tfmword(heighttab[i]) ;
/* depth */
for (i = 0; i < numdepth; i++) tfmword(depthtab[i]) ;
/* italic */
for (i = 0; i < numitalic; i++) tfmword(italictab[i]) ;
/* no lig_kern, kern, or exten */
/* param */
for (i = 0; i < numparam; i++)
if (i && (!fixrange(parameters[i]))) {
fprintf(stderr, " Parameter %d out of range (-p)!\n", i);
jumpout();
}
else tfmword(parameters[i]) ;
fprintf(stderr, "%d bytes written to tfm file.\n", totallength*4) ;
}
readcharacter()
{
FILE *fp;
if (!strcmp(filename[car], "-")) fp = stdin;
else if ((fp = fopen(filename[car], "r")) == NULL) {
fprintf(stderr, " Can't open pbm file %s!\n", filename[car]);
jumpout();
}
bitmap = pbm_readpbm(fp, &width, &height) ;
if (fp != stdin) fclose(fp) ;
if ((charflags[car] & HORZESC) == 0) horzesc[car] = width ;
if ((charflags[car] & VERTESC) == 0) vertesc[car] = 0;
if ((charflags[car] & XOFFSET) == 0) xoffset[car] = 0;
if ((charflags[car] & YOFFSET) == 0) yoffset[car] = height-1;
if ((charflags[car] & TFMWIDTH) == 0)
tfmindex[car] = add_tfmwidth(fixword(designunits(width)));
if ((charflags[car] & TFMHEIGHT) == 0)
hgtindex[car] = add_tfmheight(fixword(designunits(yoffset[car]+1)));
if ((charflags[car] & TFMDEPTH) == 0)
depindex[car] = add_tfmdepth(fixword(designunits(height-1-yoffset[car])));
if ((charflags[car] & TFMITALIC) == 0) italindex[car] = 0;
if (car < smallestch) smallestch = car;
if (car > largestch) largestch = car;
if (width > emwidth) emwidth = width ;
}
int
equal(row1, row2)
bit *row1, *row2 ;
{
integer i ;
for (i = 0; i < width; i++)
if (row1[i] != row2[i]) return (0) ;
return(1) ;
}
shipcharacter()
{
integer compsize ;
integer i, j, k ;
bit *zerorow, *onesrow ;
integer *repeatptr, *bitcounts ;
integer count ;
integer test ;
integer curptr, rowptr ;
integer bitval ;
integer repeatflag ;
integer colptr ;
integer currepeat ;
integer dynf ;
integer deriv[14] ;
integer bcompsize ;
boolean firston ;
integer flagbyte ;
boolean state ;
boolean on ;
integer hbit ;
integer pbit ;
boolean ron, son ;
integer rcount, scount ;
integer ri, si ;
integer max2 ;
integer predpkloc ;
integer buff ;
integer tfwid = widthtab[tfmindex[car]] ;
integer hesc = horzesc[car] ;
integer vesc = vertesc[car] ;
integer xoff = xoffset[car] ;
integer yoff = yoffset[car] ;
zerorow = pbm_allocrow(width) ;
onesrow = pbm_allocrow(width) ;
repeatptr =
(integer *)malloc((unsigned int)((height+1)*sizeof(integer))) ;
bitcounts =
(integer *)malloc((unsigned int)((height*width)*sizeof(integer))) ;
if (repeatptr == NULL || bitcounts == NULL) {
fprintf(stderr, " Out of memory while allocating bit counts!\n");
jumpout() ;
}
for (i = 0 ; i < width ; i++) {
zerorow[i] = PBM_WHITE ;
onesrow[i] = PBM_BLACK ;
}
for (i=0; i < height; i++) {
if (equal(bitmap[i], zerorow))
repeatptr[i] = 0 ;
else if (equal(bitmap[i], onesrow))
repeatptr[i] = 0 ;
else if (i + 1 < height && equal(bitmap[i],bitmap[i+1]))
repeatptr[i] = 1 ;
else
repeatptr[i] = 0 ;
}
i = 0 ;
while (i < height) {
k = i ;
while (repeatptr[k] == 1) k++ ;
repeatptr[i] = k - i ;
i = k + 1 ;
}
repeatptr[i] = 0 ;
colptr = width - 1 ;
repeatflag = currepeat = curptr = count = rowptr = 0 ;
test = PBM_WHITE ;
do {
colptr++ ;
if (colptr == width) {
colptr = 0 ;
rowptr = currepeat ;
if (repeatptr[currepeat] > 0) {
repeatflag = repeatptr[currepeat] ;
currepeat += repeatflag ;
rowptr += repeatflag ;
}
currepeat++ ;
}
if (rowptr >= height) bitval = -1 ;
else bitval = bitmap[rowptr][colptr] ;
if (bitval == test) count++ ;
else {
bitcounts[curptr++] = count ;
if (curptr+3 >= height*width) {
fprintf(stderr, " Out of memory while saving character counts!\n");
jumpout() ;
}
count = 1 ;
test = bitval ;
if (repeatflag > 0) {
bitcounts[curptr++] = -repeatflag ;
repeatflag = 0 ;
}
}
} while (test != -1) ;
bitcounts[curptr] = 0 ;
bitcounts[curptr + 1] = 0 ;
for (i = 1 ; i <= 13 ; i ++) deriv[i] = 0 ;
i = firston = (bitcounts[0] == 0) ;
compsize = 0 ;
while (bitcounts[i] != 0) {
j = bitcounts[i] ;
if (j == -1) compsize++ ;
else {
if (j < 0) {
compsize++ ;
j = -j ;
}
if (j < 209) compsize += 2 ;
else {
k = j - 193 ;
while (k >= 16) {
k >>= 4 ;
compsize += 2 ;
}
compsize++ ;
}
if (j < 14) (deriv[j])-- ;
else if (j < 209) (deriv[(223 - j) / 15])++ ;
else {
k = 16 ;
while (((k<<4) < j + 3)) k <<= 4 ;
if (j - k <= 192)
deriv[(207 - j + k) / 15] += 2 ;
}
}
i++ ;
}
bcompsize = compsize ;
dynf = 0 ;
for (i = 1 ; i <= 13 ; i ++) {
compsize += deriv[i] ;
if (compsize <= bcompsize) {
bcompsize = compsize ;
dynf = i ;
}
}
compsize = ((bcompsize + 1)>>1) ;
if ((compsize > ((height*width+7)>>3)) || (height*width == 0)) {
compsize = ((height*width+7)>>3) ;
dynf = 14 ;
}
flagbyte = (dynf<<4) ;
if (firston) flagbyte |= 8 ;
if ((tfwid > 16777215) || (tfwid < 0) || (hesc < 0) || (vesc != 0) ||
(compsize > 196579) || (width > 65535) || (height > 65535) ||
(xoff > 32767) || (yoff > 32767) || (xoff < -32768) || (yoff < -32768)) {
flagbyte |= 7 ;
pkbyte(flagbyte) ;
compsize += 28 ;
pkword(compsize) ;
pkword(car) ;
predpkloc = pkloc + compsize ;
pkword(tfwid) ;
pkword(hesc<<16) ;
pkword(vesc<<16) ;
pkword(width) ;
pkword(height) ;
pkword(xoff) ;
pkword(yoff) ;
} else if ((hesc > 255) || (width > 255) || (height > 255) ||
(xoff > 127) || (yoff > 127) || (xoff < -128) ||
(yoff < -128) || (compsize > 1016)) {
compsize += 13 ;
flagbyte += (compsize>>16) + 4 ;
pkbyte(flagbyte) ;
pkhalfword(compsize & 65535) ;
pkbyte(car) ;
predpkloc = pkloc + compsize ;
pkthreebytes(tfwid) ;
pkhalfword(hesc) ;
pkhalfword(width) ;
pkhalfword(height) ;
pkhalfword(xoff) ;
pkhalfword(yoff) ;
} else {
compsize += 8 ;
flagbyte = flagbyte + (compsize>>8) ;
pkbyte(flagbyte) ;
pkbyte(compsize & 255) ;
pkbyte(car) ;
predpkloc = pkloc + compsize ;
pkthreebytes(tfwid) ;
pkbyte(hesc) ;
pkbyte(width) ;
pkbyte(height) ;
pkbyte(xoff) ;
pkbyte(yoff) ;
}
if (dynf != 14) {
bitweight = 16 ;
max2 = 208 - 15 * dynf ;
i = firston ;
while (bitcounts[i] != 0) {
j = bitcounts[i] ;
if (j == - 1) pknyb(15) ;
else {
if (j < 0) {
pknyb(14) ;
j = -j ;
}
if (j <= dynf) pknyb(j) ;
else if (j <= max2) {
j -= dynf + 1 ;
pknyb((j >> 4) + dynf + 1) ;
pknyb((j & 15)) ;
} else {
j -= max2 - 15 ;
k = 16 ;
while (k <= j) {
k <<= 4 ;
pknyb(0) ;
}
while (k > 1) {
k >>= 4 ;
pknyb(j / k) ;
j = j % k ;
}
}
}
i++ ;
}
if (bitweight != 16) pkbyte(outputbyte) ;
} else {
buff = 0 ;
pbit = 8 ;
i = firston ;
hbit = width ;
on = ! firston ;
state = false ;
count = repeatflag = 0 ;
while ((bitcounts[i] != 0) || state || (count > 0)) {
if (state) {
count = rcount ;
i = ri ;
on = ron ;
repeatflag-- ;
} else {
rcount = count ;
ri = i ;
ron = on ;
}
do {
if (count == 0) {
if (bitcounts[i] < 0) {
if (! state) repeatflag = -bitcounts[i] ;
i++ ;
}
count = bitcounts[i] ;
i++ ;
on = !on ;
}
if ((count >= pbit) && (pbit < hbit)) {
if (on) buff += power[pbit] - 1 ;
pkbyte(buff) ;
buff = 0 ;
hbit -= pbit ;
count -= pbit ;
pbit = 8 ;
} else if ((count < pbit) && (count < hbit)) {
if (on) buff += power[pbit] - power[pbit - count] ;
pbit -= count ;
hbit -= count ;
count = 0 ;
} else {
if (on) buff += power[pbit] - power[pbit - hbit] ;
count -= hbit ;
pbit -= hbit ;
hbit = width ;
if (pbit == 0) {
pkbyte(buff) ;
buff = 0 ;
pbit = 8 ;
}
}
} while (hbit != width) ;
if (state && (repeatflag == 0)) {
count = scount ;
i = si ;
on = son ;
state = false ;
} else if (! state && (repeatflag > 0)) {
scount = count ;
si = i ;
son = on ;
state = true ;
}
}
if (pbit != 8) pkbyte(buff) ;
}
if (predpkloc != pkloc) {
fprintf(stderr, " Bad predicted character length: character %d!\n", car);
jumpout() ;
}
pbm_freerow(zerorow);
pbm_freerow(onesrow);
free((char *)repeatptr);
free((char *)bitcounts);
}
usage()
{
fprintf(stderr, " Usage: pbmtopk pkfile[.pk] tfmfile[.tfm] dpi\n") ;
fprintf(stderr, " [-s designsize] [-p num param...]\n");
fprintf(stderr, " [-C codingscheme ] [-F family]\n");
fprintf(stderr, " [-c num | <char>]...\n");
fprintf(stderr, " <char> is: [-W tfmwidth] [-H tfmheight] [-D tfmdepth]\n");
fprintf(stderr, " [-I ital_corr] [-h horiz] [-v vert]\n") ;
fprintf(stderr, " [-x xoffset] [-y yoffset] file\n") ;
fprintf(stderr, " or: -f optfile\n") ;
jumpout() ;
}
checkchar()
{
if (car < 0 || car >= MAXPKCHAR) {
fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
MAXPKCHAR-1) ;
jumpout() ;
}
}
optionfile(name)
char *name ;
{
FILE *fp ;
char buffer[MAXOPTLINE] ;
if (!strcmp(name, "-")) fp = stdin ;
else if ((fp = fopen(name, "r")) == NULL) {
fprintf(stderr, " Can't open option file %s!\n", name) ;
jumpout() ;
}
while (!feof(fp)) {
char *here = buffer;
if (fgets(buffer, MAXOPTLINE, fp) == NULL) break ;
while (isspace(*here)) here++ ;
if (*here && *here == '=') {
if (sscanf(here+1, "%d", &car) != 1) {
fprintf(stderr, "Bad option file line %s!\n", buffer) ;
jumpout() ;
}
} else if (*here && *here != '%' && *here != '#') {
char str[NAMELENGTH] ;
integer i, n;
checkchar() ;
if (sscanf(here, "%s%n", str, &n) != 1) {
fprintf(stderr, "Bad option file line %s!\n", buffer) ;
jumpout() ;
}
filename[car] =
(char *)malloc((unsigned int)(sizeof(char)*(strlen(str)+1))) ;
strcpy(filename[car], str) ;
for (i = 1; i < 256; i<<=1) {
here += n;
if (sscanf(here, "%s%n", str, &n) != 1) break ;
if (strcmp(str, "*")) {
charflags[car] |= i ;
switch (i) {
case XOFFSET:
xoffset[car] = atoi(str) ;
break ;
case YOFFSET:
yoffset[car] = atoi(str) ;
break ;
case HORZESC:
horzesc[car] = atoi(str) ;
break ;
case VERTESC:
vertesc[car] = atoi(str) ;
break ;
case TFMWIDTH:
tfmindex[car] = add_tfmwidth(fixword(atof(str))) ;
break ;
case TFMHEIGHT:
hgtindex[car] = add_tfmheight(fixword(atof(str))) ;
break ;
case TFMDEPTH:
depindex[car] = add_tfmdepth(fixword(atof(str))) ;
break ;
case TFMITALIC:
italindex[car] = add_tfmitalic(fixword(atof(str))) ;
break ;
}
}
}
car++ ;
}
}
if (fp != stdin) fclose(fp) ;
}
dialog(gargc, gargv)
int gargc ;
char **gargv ;
{
integer i, hesc, vesc, xoff, yoff, tfwid, tfdep, tfhgt, tfital ;
byte flags ;
if (--gargc < 1) usage() ;
strcpy(pkname, *++gargv) ;
add_suffix(pkname, "pk") ;
if (--gargc < 1) usage() ;
strcpy(tfmname, *++gargv) ;
add_suffix(tfmname, "tfm") ;
if (--gargc < 1) usage() ;
resolution = atoi(*++gargv) ;
if (resolution < 1 || resolution > 32767) {
fprintf(stderr, " Unlikely resolution %d dpi!\n", resolution);
jumpout();
}
car = flags = hesc = vesc = xoff = yoff = tfwid = 0;
while (++gargv, --gargc) {
if (gargv[0][0] == '-' && gargv[0][1]) {
char c, *p;
c = gargv[0][1] ;
if (gargv[0][2]) p = *gargv + 2 ;
else if (++gargv, --gargc) p = *gargv ;
else usage() ;
switch (c) {
case 'C':
codingscheme = p;
break ;
case 'F':
familyname = p;
break ;
case 'c':
car = atoi(p) ;
break ;
case 's':
designsize = fixword(atof(p));
if (designsize < 1048576) {
fprintf(stderr, " Design size %f out of range!\n",
unfixword(designsize));
jumpout() ;
}
case 'h':
hesc = atoi(p) ;
flags |= HORZESC ;
break ;
case 'v':
vesc = atoi(p) ;
flags |= VERTESC ;
break ;
case 'x':
xoff = atoi(p) ;
flags |= XOFFSET ;
break ;
case 'y':
yoff = atoi(p) ;
flags |= YOFFSET ;
break ;
case 'W':
tfwid = fixword(atof(p)) ;
flags |= TFMWIDTH ;
break ;
case 'H':
tfhgt = fixword(atof(p)) ;
flags |= TFMHEIGHT ;
break ;
case 'D':
tfdep = fixword(atof(p)) ;
flags |= TFMDEPTH ;
break ;
case 'I':
tfital = fixword(atof(p)) ;
flags |= TFMITALIC ;
break ;
case 'f':
optionfile(p) ;
break ;
case 'p':
numparam = atoi(p);
if (numparam < 1 || numparam > 30) {
fprintf(stderr, " Parameter count %d out of range!\n", numparam);
jumpout();
}
for (i=0; i<numparam; i++)
if (++gargv,--gargc) parameters[i] = fixword(atof(*gargv)) ;
else {
fprintf(stderr, " Not enough parameters (-p)!\n");
jumpout() ;
}
break ;
default:
usage() ;
}
} else {
checkchar() ;
if (flags & TFMWIDTH)
tfmindex[car] = add_tfmwidth(tfwid);
if (flags & TFMDEPTH)
depindex[car] = add_tfmdepth(tfdep);
if (flags & TFMHEIGHT)
hgtindex[car] = add_tfmheight(tfhgt);
if (flags & TFMITALIC)
italindex[car] = add_tfmitalic(tfital);
horzesc[car] = hesc ;
vertesc[car] = vesc ;
xoffset[car] = xoff ;
yoffset[car] = yoff ;
filename[car] = *gargv ;
charflags[car] = flags ;
car++ ;
flags = 0;
}
}
}
main(argc, argv)
int argc ;
char *argv[] ;
{
initialize() ;
dialog(argc, argv) ;
hppp = round((resolution<<16) / 72.27) ;
add_suffix(pkname, "pk") ;
add_suffix(tfmname, "tfm") ;
if (!strcmp(pkname, "-")) pkfile = stdout;
else if ((pkfile = fopen(pkname, "w")) == NULL) {
fprintf(stderr, " Can't open PK file %s!\n", pkname);
jumpout() ;
}
if (!strcmp(tfmname, "-")) tfmfile = stdout ;
else if ((tfmfile = fopen(tfmname, "w")) == NULL) {
fprintf(stderr, " Can't open TFM file %s!\n", tfmname);
jumpout();
}
writepreamble() ;
for (car = 0 ; car < MAXPKCHAR ; car++)
if (filename[car]) {
readcharacter() ;
shipcharacter() ;
}
writepostamble() ;
writetfmfile() ;
if (pkfile != stdout) fclose(pkfile) ;
if (tfmfile != stdout) fclose(tfmfile) ;
exit(0);
}